using System;
using System.Collections.Generic;
using System.Text;
using MCromwell.StaffIntranet.Core;
using MCromwell.StaffIntranet.DTO;
using MCromwell.StaffIntranet.DependencyInjection;
using MCromwell.StaffIntranet.Task.Infrastructure;
using Mapper;

namespace MCromwell.StaffIntranet.Task.Tasks
{
    
    public class StaffManagementTask : AbstractTask, IStaffManagementTask
    {
        private IStaffRepository staffRepository = null;
        private ISpecification<Staff> validPhotoSpecification;
        private ISpecification<Staff> uniqueNameSpecification;
        
        public StaffManagementTask(IStaffRepository staffRepository)
        {
            if (staffRepository == null)
                throw new ArgumentNullException("staffRepository", "staffRepository cannot be null");

            this.staffRepository = staffRepository;
            validPhotoSpecification = new ValidStaffPhotoSpecification();
            uniqueNameSpecification = new UniqueStaffNameSpecification(staffRepository);
        }
        
        [WrapExceptionWith(typeof(ProblemSavingStaffException))]
        public int SaveChangesUsing(StaffDTO staffDetails, out NotificationDTO notification)
        {
            var staffMapper = SimpleObjectMapperContainer.RetrieveMapper<StaffDTO, Staff>();
            var validationMapper = SimpleObjectMapperContainer.RetrieveMapper<DomainObjectValidationResult, NotificationDTO>();
            Staff staffToUpdate = staffMapper.Apply(staffDetails);
                        
            DomainObjectValidationResult validationResult = staffToUpdate.Validate();
            validationResult.Merge(uniqueNameSpecification.ResultsOf(staffToUpdate).Results);
            
            if (staffDetails.Photo.SaveOption == PhotoSaveOption.Update)
            {
                DomainObjectValidationResult photoValidationResult = validPhotoSpecification.ResultsOf(staffToUpdate);
                validationResult.Merge(photoValidationResult.Results);
            }

            if (validationResult.IsValid)
            {
                notification = NotificationDTO.Empty;
                if (staffDetails.Photo.SaveOption == PhotoSaveOption.Update)
                    return staffRepository.Update(staffToUpdate, StaffPhotoSavingOptions.Update);
                else if (staffDetails.Photo.SaveOption == PhotoSaveOption.Clear)
                    return staffRepository.Update(staffToUpdate, StaffPhotoSavingOptions.Clear);
                else
                    return staffRepository.Update(staffToUpdate, StaffPhotoSavingOptions.Leave);
            }
            else
            {
                notification = validationMapper.Apply(validationResult);
                return -1;
            }
                       
        }

        #region IStaffManagementTask Members

        [WrapExceptionWith(typeof(ProblemDeletingStaffException))]
        public void DeleteStaffBy(int staffId)
        {
            staffRepository.DeleteStaffBy(staffId);
        }

        #endregion
    }
}
